/*
 * @(#)TestsetType.java
 *
 *
 *
 * ver 1.0 Aug 16, 2007 ggranum
 */
package org.testfire.model;

import java.util.*;
import org.testfire.model.exception.CannotCreateDocumentException;
import org.testfire.model.exception.CannotParseObjectException;
import org.testfire.translator.TranslatorFactory;
import org.testfire.util.DomReader;
import org.testfire.util.DomUtil;
import org.w3c.dom.Element;

public class TestsetType implements TestFireObject
{

    private TestFireObject parent;

    private Map<String, String> variableKeys = new HashMap<String, String>();

    private final Element element;

    public TestsetType( String fullyQualifiedXmlAsString ) throws
        CannotCreateDocumentException, CannotParseObjectException
    {
        try
        {
            element = DomReader.getDocument( fullyQualifiedXmlAsString ).getDocumentElement();
        }
        catch ( Exception e )
        {
            throw new CannotCreateDocumentException( e );
        }

    }

    public TestsetType( Element element ) throws CannotParseObjectException
    {
        this.element = element;
    }

    public Object translate( TestsetType testset )
    {
        return TranslatorFactory.translate( testset, this );
    }

    public void setParent( TestFireObject parent )
    {
        this.parent = parent;
    }

    public TestFireObject getParent()
    {
        return parent;
    }

    public String getName()
    {
        return element.getAttribute( "name" );
    }

    public void setName( String name )
    {
        element.setAttribute( "name", name );
    }

    public Date getCreated()
    {
        return DomUtil.toJavaDate( element.getAttribute( "created" ) );
    }

    public void setCreated( Date created )
    {
        element.setAttribute( "created", DomUtil.toXMLDate( created ) );
    }

    public Date getLastVerified()
    {
        return DomUtil.toJavaDate( element.getAttribute( "lastVerified" ) );
    }

    public void setLastVerified( Date lastVerified )
    {
        element.setAttribute( "lastVerified", DomUtil.toXMLDate( lastVerified ) );
    }

    public String getForBug()
    {
        return element.getAttribute( "forBug" );
    }

    public void setForBug( String forBug )
    {
        element.setAttribute( "forBug", forBug );
    }

    public String getDescription()
    {
        return element.getAttribute( "description" );
    }

    public void setDescription( String description )
    {
        element.setAttribute( "description", description );
    }

    public String getClassPackage()
    {
        return element.getAttribute( "package" );
    }

    public void setClassPackage( String classPackage )
    {
        element.setAttribute( "package", classPackage );
    }

    public String getUserName()
    {
        return element.getAttribute( "userName" );
    }

    public void setUserName( String userName )
    {
        element.setAttribute( "userName", userName );
    }

    public Engine getEngine()
    {
        return new Engine( DomUtil.getChildElementByTagName( "tf:engine", element ) );
    }

    public VersionType getMinVersion()
    {
        return new VersionType( DomUtil.getChildElementByTagName( "tf:minVersion", element ), "Min" );
    }

    public VersionType getMaxVersion()
    {
        return new VersionType( DomUtil.getChildElementByTagName( "tf:maxVersion", element ), "Max" );
    }

    public TestType getSetUp()
    {
        return new TestType( DomUtil.getChildElementByTagName( "tf:setUp", element ) );
    }

    public List<TestType> getTests()
    {

        List<Element> testNodes = DomUtil.getChildElementsByTagName( "tf:test", element );
        List<TestType> tests = new ArrayList<TestType>( testNodes.size() * 2 );
        for ( Element e : testNodes )
        {
            tests.add( new TestType( e ) );
        }
        return tests;
    }

    public List<TestsetResultType> getTestsetResults()
    {

        List<Element> resultNodes = DomUtil.getChildElementsByTagName( "tf:TestsetResult", element );
        List<TestsetResultType> testsetResults = new ArrayList<TestsetResultType>( resultNodes.size() * 2 );
        for ( Element e : resultNodes )
        {
            testsetResults.add( new TestsetResultType( this, e ) );
        }
        return testsetResults;
    }

    public TestType getTearDown()
    {
        return new TestType( DomUtil.getChildElementByTagName( "tf:tearDown", element ) );
    }

    public void registerVariableKey( String key, String type )
    {
        if ( this.variableKeys.containsKey( key ) )
        {
            String currentType = this.variableKeys.get( key );
            if ( !currentType.equals( type ) )
            {
                throw new RuntimeException( String.format( "Variable Key %1$s already exists and is of type %2$s. "
                    + "Cannot replace with type %3$s", key, currentType, type ) );
            }
        }
        else
        {
            this.variableKeys.put( key, type );
        }
    }

    public Map<String, String> getVariableKeys()
    {
        return variableKeys;
    }

    public Element getElement()
    {
        return element;
    }

    public List<TestResultType> getTestResults(TestsetResultType forTestsetRun)
    {
        List<TestType> tests = this.getTests();
        List<TestResultType> testResults = new ArrayList<TestResultType>( );
        for(TestType t : tests){
            TestResultType result =  t.getTestResult( forTestsetRun.getRunDate() );
            if(result != null)
            {
                testResults.add( result );
            }
        }

        return testResults;
    }
}

// eof: TestsetType.java